package com.yneusoft.pctask.service;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.mongodb.client.gridfs.model.GridFSFile;
import com.yneusoft.common.enums.ResultEnum;
import com.yneusoft.common.handler.MyException;
import com.yneusoft.common.model.ResponseWrapper;
import com.yneusoft.common.tool.CommonTool;
import com.yneusoft.common.tool.DataProcessing;
import com.yneusoft.common.tool.PageTool;
import com.yneusoft.dao.entity.Department;
import com.yneusoft.dao.entity.DepartmentStaff;
import com.yneusoft.dao.entity.Staff;
import com.yneusoft.dao.entity.StaffState;
import com.yneusoft.dao.mapper.DepartmentMapper;
import com.yneusoft.dao.mapper.DepartmentStaffMapper;
import com.yneusoft.dao.mapper.StaffMapper;
import com.yneusoft.pctask.mapper.StaffManageMapper;
import com.yneusoft.pctask.model.*;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.gridfs.GridFsOperations;
import org.springframework.data.mongodb.gridfs.GridFsResource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @Description： 员工信息业务层
 * @Author: zwl
 * @Date: 2021/11/24 19:01
 */
@Service
public class StaffManageService {
    //员工信息列表 ---> 接口
    @Autowired
    private StaffManageMapper staffManageMapper;
    @Autowired
    private StaffMapper staffMapper;

    //员工部门关联信息列表 ---> 接口
    @Autowired
    DepartmentStaffMapper departmentStaffMapper;

    //部门列表 ---> 接口
    @Autowired
    private DepartmentMapper departmentMapper;

    //员工附件aid
    String enclosureId = "";

    //附件上传、下载、删除
    private final GridFsOperations gridFsOperations;
    public StaffManageService(GridFsOperations gridFsOperations) {
        this.gridFsOperations = gridFsOperations;
    }

    /**
     * 1、获取员工状态列表
     * @return   员工状态信息列表
     */
    public ResponseWrapper getStaffStateList(){
        return ResponseWrapper.markSuccess(StaffState.dataList);
    }

    /**
     * 2、获取员工信息列表
     * @param pageSearchParam
     * @return  员工信息列表
     */
    public ResponseWrapper getStaffList(PageSearchParam pageSearchParam){
        //总计数
        GetStaffListNumResult getStaffListNumResult = new GetStaffListNumResult();

        //对模糊查询进行计算总条数
        LambdaQueryWrapper<Staff> getRowsNum = new LambdaQueryWrapper<>();
        if (pageSearchParam.getSearchKey() != null && !pageSearchParam.getSearchKey().equals(" ")){
            getRowsNum.like(Staff::getName,pageSearchParam.getSearchKey());
        }
        //对员工状态查询进行计算总条数
        if (pageSearchParam.getStateId() != null){
            getRowsNum.eq(Staff::getStateId,pageSearchParam.getStateId());
        }
        //查询总数
        Integer rowsNum = staffMapper.selectCount(getRowsNum);
        getStaffListNumResult.setRowsNum(rowsNum);

        //对分页进行判断
        if (pageSearchParam.getSearchKey() != null){
            pageSearchParam.setSearchKey("%" + pageSearchParam.getSearchKey() + "%");
        }else {
            pageSearchParam.setSearchKey("%%");
        }
        //计算分页
        pageSearchParam.setPage(PageTool.getPageIndex(pageSearchParam.getPage(),pageSearchParam.getPageSize()));

        //获取员工信息列表
        List<Map<String, Object>> staffList = staffManageMapper.getStaffList(pageSearchParam);
        List<GetStaffListResult> getStaffListResults = CommonTool.mapListToBeanList(staffList, GetStaffListResult.class);
        //遍历员工信息
        for (GetStaffListResult each : getStaffListResults) {
            //获取附件的名称
            GridFSFile id = gridFsOperations.findOne(Query.query(Criteria.where("_id").is(each.getEnclosureId())));
            //对获取到的附件名称进行判断
            if(id != null){
                each.setEnclosureName(id.getFilename());
            }else {
                each.setEnclosureName("");
            }
            //获取部门的名称
            Map<String, Object> departmentName = staffManageMapper.getDepartmentName(each.getAid());
            if(departmentName == null) {
                each.setDepartmentList("");
            }
            else {
                each.setDepartmentList(departmentName.get("departmentName").toString());
            }
        }

        getStaffListNumResult.setList(getStaffListResults);
        return ResponseWrapper.markSuccess(getStaffListNumResult);
    }

    /**
     * 3、员工离职/重新入职
     * @param updateStaffStateParam
     * @return  修改的信息
     */
    @Transactional(rollbackFor = Exception.class)
    public ResponseWrapper updateStaffState(UpdateStaffStateParam updateStaffStateParam)  {
        //时间
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String time = DataProcessing.getFormatTime(null);
        LocalDateTime localDateTime = LocalDateTime.parse(time, formatter);

        //通过员工的aid获取员工的信息
        Staff staffList = staffMapper.selectById(updateStaffStateParam.getAid());
        if (staffList == null){
            throw new MyException("该员工信息不存在，请重新输入！");
        }
        //对员工的状态信息进行判断
        if (staffList.getStateId().intValue() == updateStaffStateParam.getStateId().intValue() && updateStaffStateParam.getStateId() == 0){
            throw new MyException("该员工已离职!");
        }
        if (staffList.getStateId().intValue() == updateStaffStateParam.getStateId().intValue() && updateStaffStateParam.getStateId() == 1){
            throw new MyException("该员工已入职!");
        }
        if (updateStaffStateParam.getStateId() != 0 && updateStaffStateParam.getStateId() != 1){
            throw new MyException("只能修改员工状态为 0(离职) 或 1(入职),请重新输入！");
        }

        //员工状态信息
        staffList.setStateId(updateStaffStateParam.getStateId());
        staffList.setStateName(updateStaffStateParam.getStateId() == 0?"离职":"在职");
        //员工状态信息更新时间
        staffList.setUpdateTime(localDateTime);
        //修改员工状态
        staffMapper.updateById(staffList);
        return ResponseWrapper.markSuccess();

    }

    /**
     * 4、【新增/修改】获取部门列表
     * @return 部门信息列表
     */
    public ResponseWrapper getDepartmentInfoList(){
        //获取部门信息列表
        List<Department> departments = departmentMapper.selectList(null);
        List<GetDepartmentInfoListResult> getDepartmentInfoListResults = JSON.parseArray(JSON.toJSONString(departments)).toJavaList(GetDepartmentInfoListResult.class);
        return ResponseWrapper.markSuccess(getDepartmentInfoListResults);
    }

    /**
     * 5、【新增/修改】修改时获取员工信息
     * @param staffListParam
     * @return  员工信息
     */
    public ResponseWrapper getStaffInfo(StaffListParam staffListParam){
        //通过员工的aid获取员工信息列表
        Staff staff = staffMapper.selectById(staffListParam.getAid());
        //对获取到的员工信息进行判断
        if(staff == null) {
            throw new MyException("该员工信息不存在！请重新输入！");
        }
        //获取到对应的员工的信息
        GetStaffInfoResult getStaffInfoResult = JSON.parseObject(JSON.toJSONString(staff),GetStaffInfoResult.class);

        //获取附件的名称
        GridFSFile id = gridFsOperations.findOne(Query.query(Criteria.where("_id").is(getStaffInfoResult.getEnclosureId())));
        //对获取到的附件名称进行判断
        if(id != null){
            getStaffInfoResult.setEnclosureName(id.getFilename());
        }else {
            getStaffInfoResult.setEnclosureName("");
        }

        //获取所属部门列表的部门aid
        LambdaQueryWrapper<DepartmentStaff> getDepartmentAids = new LambdaQueryWrapper<>();
        getDepartmentAids.eq(DepartmentStaff::getStaffAid,staff.getAid());
        //通过部门的aid查询出员工部门关联信息列表
        List<DepartmentStaff> departmentStaffs = departmentStaffMapper.selectList(getDepartmentAids);
        //集合存放查询出来的部门的aid
        List<Integer> departmentAids = new ArrayList<>();
        //遍历员工部门关联列表
        for (DepartmentStaff each : departmentStaffs) {
            //将部门的aid放入到集合中
            departmentAids.add(each.getDepartmentAid());
        }

        //放入员工信息列表中并返回结果
        getStaffInfoResult.setDepartmentList(departmentAids);
        return ResponseWrapper.markSuccess(getStaffInfoResult);
    }

    /**
     * 6、【新增/修改】新增/员工信息
     * @return  code / message / data
     */
    @Transactional(rollbackFor = Exception.class)
    public ResponseWrapper saveStaffInfo(SaveStaffInfoParam saveStaffInfoParam){
        //初始员工的aid
        Integer aid = saveStaffInfoParam.getAid();

        //获取需要新增的员工信息列表
        Staff newStaff = JSON.parseObject(JSON.toJSONString(saveStaffInfoParam)).toJavaObject(Staff.class);

        if (saveStaffInfoParam.getAid() == -1){
            //新增员工信息
            staffMapper.insert(newStaff);
            //获取新增之后员工的aid
            aid = newStaff.getAid();

        }else {
            //修改员工信息
            staffMapper.updateById(newStaff);
        }

        //删除员工原有的部门关联的关系
        LambdaQueryWrapper<DepartmentStaff> deleteDepartment = new LambdaQueryWrapper<>();
        deleteDepartment.eq(DepartmentStaff::getStaffAid,aid);
        departmentStaffMapper.delete(deleteDepartment);

        //将新增的员工的信息列入员工部门关联信息列表中
        List<Integer> departmentStaffList = saveStaffInfoParam.getDepartmentList();
        //遍历员工部门关联信息列表
        for (Integer departmentAid : departmentStaffList) {
            DepartmentStaff newDepartmentStaff = new DepartmentStaff();
            //当前员工的aid
            newDepartmentStaff.setStaffAid(aid);
            if (staffMapper.selectById(aid) == null){
                throw new MyException("该员工信息不存在,不能修改,请重新输入！");
            }

            newDepartmentStaff.setDepartmentAid(departmentAid);
            //新增部门的aid
            if(departmentMapper.selectById(departmentAid) == null){
                throw new MyException("该部门不存在,请重新输入！");
            }

            //新增部门信息
            departmentStaffMapper.insert(newDepartmentStaff);
        }
        return ResponseWrapper.markSuccess();
    }

    /**
     * 7、【新增/修改】检查身份证号是否重复
     * @param checkIdNumberIsExistParam
     * @return 员工信息 / true / false
     */
    public ResponseWrapper checkIdNumberIsExist(CheckIdNumberIsExistParam checkIdNumberIsExistParam){
        //定义员工布尔值  默认为 true
        boolean isExist = true;
        //获取员工的idNumber
        LambdaQueryWrapper<Staff> getStaffIdNumber = new LambdaQueryWrapper<>();
        getStaffIdNumber.eq(Staff::getIdNumber,checkIdNumberIsExistParam.getIdNumber());
        //根据员工的idNumber获取员工信息列表
        Staff staff = staffMapper.selectOne(getStaffIdNumber);
        //对获取到的员工信息列表进行判断
        if (staff == null){
            return ResponseWrapper.markSuccess(new CheckIdNumberIsExistResult(false,null));
        }
        CheckStaffIdNumberResult staffIdNumberResult = JSON.parseObject(JSON.toJSONString(staff)).toJavaObject(CheckStaffIdNumberResult.class);

        //获取员工部门关联列表的部门aid
        LambdaQueryWrapper<DepartmentStaff> getDepartmentAid = new LambdaQueryWrapper<>();
        getDepartmentAid.eq(DepartmentStaff::getStaffAid,staff.getAid());
        List<DepartmentStaff> departmentStaffs = departmentStaffMapper.selectList(getDepartmentAid);
        //集合
        List<Integer> departmentList = new ArrayList<>();
        //遍历员工信息关联表
        for (DepartmentStaff each : departmentStaffs) {
            departmentList.add(each.getDepartmentAid());
        }
        staffIdNumberResult.setDepartmentList(departmentList);

        //获取附件的名称
        GridFSFile id = gridFsOperations.findOne(Query.query(Criteria.where("_id").is(staffIdNumberResult.getEnclosureId())));
        //对获取到的附件名称进行判断
        if(id != null){
            staffIdNumberResult.setEnclosureName(id.getFilename());
        }else {
            staffIdNumberResult.setEnclosureName("");
        }
        //对员工的aid进行判断
        if (checkIdNumberIsExistParam.getAid().equals(staff.getAid())){
            isExist = false;
        }
        CheckIdNumberIsExistResult idNumberResult = new CheckIdNumberIsExistResult(isExist, staffIdNumberResult);
        if (!isExist){
            idNumberResult.setStaffInfo(null);
        }
        return ResponseWrapper.markSuccess(idNumberResult);

    }

    /**
     * 8、【新增/修改】检查手机号是否存在
     * @param checkPhoneStaffParam
     * @return  员工信息 / true / false
     */
    public ResponseWrapper checkPhoneIsExist(CheckStaffPhoneParam checkPhoneStaffParam){
        //定义员工布尔值  默认为 true
        boolean isExist = true;
        //通过手机号查询出员工信息
        LambdaQueryWrapper<Staff> getStaffPhone = new LambdaQueryWrapper<>();
        getStaffPhone.eq(Staff::getPhone,checkPhoneStaffParam.getPhone());
        Staff staff = staffMapper.selectOne(getStaffPhone);
        //对查询出来的员工信息进行判断
        if (staff == null){
            return ResponseWrapper.markSuccess(new CheckPhoneIsExistResult(false,null));
        }
        //根据手机号获取对应的员工的信息列表
        CheckStaffPhoneResult staffPhoneResult = JSON.parseObject(JSON.toJSONString(staff)).toJavaObject(CheckStaffPhoneResult.class);

        //根据员工的aid获取对应的部门aid
        LambdaQueryWrapper<DepartmentStaff> getDepartmentAid = new LambdaQueryWrapper<>();
        getDepartmentAid.eq(DepartmentStaff::getStaffAid,staff.getAid());
        List<DepartmentStaff> departmentStaffs = departmentStaffMapper.selectList(getDepartmentAid);
        //集合
        List<Integer> departmentList = new ArrayList<>();
        //遍历员工部门关联表
        for (DepartmentStaff each : departmentStaffs) {
            departmentList.add(each.getDepartmentAid());
        }
        staffPhoneResult.setDepartmentList(departmentList);

        //获取附件的名称
        GridFSFile id = gridFsOperations.findOne(Query.query(Criteria.where("_id").is(staffPhoneResult.getEnclosureId())));
        //对获得的附件的id进行判断
        if (id != null){
            staffPhoneResult.setEnclosureName(id.getFilename());
        }else {
            staffPhoneResult.setEnclosureName("");
        }
        //员工的aid进行判断
        if (checkPhoneStaffParam.getAid().equals(staff.getAid())){
            isExist = false;
        }
        CheckPhoneIsExistResult phoneResult = new CheckPhoneIsExistResult(isExist, staffPhoneResult);
        if (!isExist){
            phoneResult.setStaffInfo(null);
        }
        return ResponseWrapper.markSuccess(phoneResult);
    }

    /**
     * 9、【新增/修改】上传员工附件
     * @param param 员工aid和附件
     * @return 附件id和附件名称
     */
    public ResponseWrapper uploadStaffFile(UploadStaffFileParam param){
        MultipartFile file = param.getFile();

        //对上传的文件进行判断
        if (file == null){
            throw new MyException("文件异常,请选择需要上传的文件！");
        }

        try (InputStream inputStream = file.getInputStream()) {
            //上传文件返回文件ID
            ObjectId objectId = gridFsOperations.store(inputStream, file.getOriginalFilename(), file.getContentType());
            enclosureId = objectId.toString();

            return ResponseWrapper.markSuccess(new UploadStaffFileResult(enclosureId, file.getOriginalFilename()));

        } catch (IOException ioException) {
            ioException.printStackTrace();
            return ResponseWrapper.markError(ResultEnum.FAILED,"上传失败！");
        }
    }

    /**
     * 10、【新增/修改】删除员工附件
     * @param param 员工aid、附件id
     * @return 操作结果
     */
    public ResponseWrapper delStaffFile(DeleteStaffFileParam param) {
        //获取传入的附件id
        String enclosureId = param.getEnclosureId();
        //删除附件id
        gridFsOperations.delete(Query.query(Criteria.where("_id").is(enclosureId)));
        if (param.getStaffAid() != -1){
            LambdaUpdateWrapper<Staff> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(Staff::getAid,param.getStaffAid()).set(Staff::getEnclosureId,null);
            staffMapper.update(null,updateWrapper);
        }
        return ResponseWrapper.markSuccess();
    }

    /**
     * 11、下载员工附件
     * @param response 请求对象
     * @param enclosureId 附件id
     * @return 附件下载
     */
    public ResponseWrapper downloadFile(HttpServletResponse response, String enclosureId) {
        if(enclosureId == null) {
            return ResponseWrapper.markError(ResultEnum.FAILED,"文件id为空，请检查！");
        }
        //根据文件ID查询出文件
        GridFSFile gridFsFile = gridFsOperations.findOne(Query.query(Criteria.where("_id").is(enclosureId)));
        if (gridFsFile != null) {
            GridFsResource gridFsResource = gridFsOperations.getResource(gridFsFile);
            //设置响应对象的响应内容的类型
            response.setCharacterEncoding("UTF-8");
            response.setContentType(gridFsResource.getContentType());
            response.setHeader("Content-Disposition", "attachment;filename=" + new String(gridFsFile.getFilename().getBytes(), StandardCharsets.ISO_8859_1));
            try (OutputStream outputStream = response.getOutputStream();
                 InputStream inputStream = gridFsResource.getInputStream()) {
                //读取inputStream中的所有字节并写入输出流中
                outputStream.write(inputStream.readAllBytes());
                return ResponseWrapper.markSuccess("下载成功！");
            } catch (IOException ioException) {
                ioException.printStackTrace();
            }
        }
        return ResponseWrapper.markError(ResultEnum.FAILED,"文件不存在！");
    }
}
